#pragma once
#ifndef _KH_CORE_LOGGER_H
#define _KH_CORE_LOGGER_H
#include <Kharlia/Core/Common.h>

#define _DECL_FUNC(name) \
    void name(object msg) const;\
    void name(str msg) const;\
    void name(unicode msg) const;\
    void name(boost::format& fmt) const

namespace kharlia { namespace core {
    enum ELogLevel {
        LL_NOTSET = 0,
        LL_DEBUG = 10,
        LL_INFO = 20,
        LL_WARNING = 30,
        LL_ERROR = 40,
        LL_CRITICAL = 50
    };

    // This class exposes an instance of the python logging.Logger class to C++
    // The constructor calls the function kharlia.core.get_logger with the
    // logger name as the parameter, that function should be defined before
    // the C++ module is initialized.
    class KH_CORE_API FLogger: public boost::noncopyable {
        object LoggerObject;
        object DebugFunc;
        object InfoFunc;
        object WarningFunc;
        object ErrorFunc;
        object CriticalFunc;
        object ExceptionFunc;
        object LogFunc;
    
        FLogger(str name);

    public:
        _DECL_FUNC(Debug);
        _DECL_FUNC(Info);
        _DECL_FUNC(Warning);
        _DECL_FUNC(Error);
        _DECL_FUNC(Critical);
        _DECL_FUNC(Exception);
        void Log(ELogLevel level, object msg) const;
        void Log(ELogLevel level, str msg) const;
        void Log(ELogLevel level, unicode msg) const;
        void Log(ELogLevel level, boost::format& fmt) const;

        static shared_ptr<FLogger> GetLogger(str name);
        static shared_ptr<FLogger> GetLogger(unicode name);
    };
}}

#undef _DECL_FUNC

#endif